package com.bs.demo.Aspect;

import com.bs.common.utils.Result;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author bingshao
 * @date 2022/12/8
 **/
@Component
@Aspect
@Log4j2
public class LogAspect {

    //        @Pointcut(value = "execution(* com.bs.demo.controller..*.*(..))")
    @Pointcut(value = "@annotation(com.bs.demo.annotation.BingShaoLog)")
    public void pointcut() {
    }


    @Before(value = "pointcut()")
    public void before(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        log.info("aop执行之前args==============>{}", args);
        // 此处也可以获取到请求头
//        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
//        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
//        HttpServletRequest request = sra.getRequest();
//        Enumeration<String> headerNames = request.getHeaderNames();
//        while (headerNames.hasMoreElements()) {
//            log.info("headerName========={}", headerNames.nextElement());
//        }
    }

    @After(value = "pointcut()")
    public void after(JoinPoint joinPoint) {
        // 异常也返回
        Object[] args = joinPoint.getArgs();

        log.info("aop执行之后signature==============>{}", joinPoint.getSignature());
//        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
//        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
//        HttpServletResponse response = sra.getResponse();
//        response.setStatus(200);
    }

    @Around(value = "pointcut()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        log.info("aop执行环绕前args==============>{}", args);

        // 可以修改入参，解密等等
//        Arrays.stream(args).forEach(arg -> {
//            ((TestVo) arg).setName("倾月");
//            ((TestVo) arg).setSex("女");
//        });
        Result result = (Result) proceedingJoinPoint.proceed(args);
//        result.setCode(500);
        log.info("aop执行环绕后result==============>{}", result);
    }

    @AfterReturning(value = "pointcut()", returning = "result")
    public void afterReturn(Result result) {
        // 成功才返回
        log.info("aop after return==============>{}", result);
    }

    @AfterThrowing(value = "pointcut()", throwing = "throwable")
    public void afterThrowing(Throwable throwable) {
        // 异常返回
        log.warn("aop after throwing=======》{}", throwable.getMessage());
    }
}
